package com.arpa.wms.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.wms.domain.consts.NumConst;
import com.arpa.wms.domain.dto.InboundItemDTO;
import com.arpa.wms.domain.entity.InboundItem;
import com.arpa.wms.domain.vo.InboundItemVO;
import com.arpa.wms.mapper.InboundItemMapper;
import com.arpa.wms.service.IInboundItemService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.arpa.wms.domain.consts.NumConst.NUM_ZERO;

/**
 * <p>
 * 入库单明细 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-08-04
 */
@Service
public class InboundItemServiceImpl extends ServiceImpl<InboundItemMapper, InboundItem> implements IInboundItemService {

    @Autowired
    private PartyCache partyCache;

    /**
     * 保存
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public boolean save(InboundItem entity) {
        if(StringUtils.isBlank(entity.getCode())){
            entity.setCode(IdUtil.simpleUUID());
        }
        if(StringUtils.isBlank(entity.getCreatedBy())){
            entity.setCreatedBy(UserUtil.getCode());
        }
        return super.save(entity);
    }

    /**
     * 根据code更新实体
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public int updateByCode(InboundItem entity) {
        if(StringUtils.isBlank(entity.getModifiedBy())){
            entity.setModifiedBy(UserUtil.getCode());
        }
        return baseMapper.update(entity,new QueryWrapper<InboundItem>().lambda().eq(InboundItem::getCode,entity.getCode()).eq(InboundItem::getGroupCode,UserUtil.getBranchCode()));
    }

    /**
     * 查询列表
     * @param inboundItemDTO
     * @return
     */
    @Override
    public List<InboundItemVO> queryList(InboundItemDTO inboundItemDTO){
        //排序字段名需要驼峰转数据库下划线类型字段名
        if(StringUtils.isNotEmpty(inboundItemDTO.getSortField())){
            inboundItemDTO.setSortField(CommonUtil.camel2Underline(inboundItemDTO.getSortField()));
        }
        List<InboundItemVO> inboundItemVOList = baseMapper.queryList(inboundItemDTO);
        return inboundItemVOList;
    }

    /**
     * 查询合计,包含总数
     * @param inboundItemDTO
     * @return
     */
    @Override
    public InboundItemVO queryListSum(InboundItemDTO inboundItemDTO){
        InboundItemVO inboundItemVO = baseMapper.queryListSum(inboundItemDTO);
        return inboundItemVO;
    }

    /**
     *
     * @param putawayCode
     * @return
     */
    @Override
    public int updateInventoryInfoByPutawayCode(String putawayCode){
        return this.baseMapper.updateInventoryInfoByPutawayCode(putawayCode,UserUtil.getBranchCode());
    }

    /**
     * 获取入库明细详细信息，
     * 用于零散合同修改、启用时使用
     *
     * @param warehouseCode 仓库标识
     * @param goodsCode     商品标识
     * @param receiveLot    收货批号
     * @return
     */
    @Override
    public Map<String, Object> getItemInfo(String warehouseCode, String goodsCode, String receiveLot) {
        return this.baseMapper.getItemInfo(warehouseCode,goodsCode,receiveLot,UserUtil.getBranchCode());
    }



    /**
     * 批量插入入库单
     *
     * @param inboundItems
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void batchInsert(List<InboundItem> inboundItems) {
        String createdBy = UserUtil.getCode();
        String createdName = partyCache.translate(createdBy);
        LocalDateTime nowTime = LocalDateTime.now();
        StringBuilder sql = new StringBuilder();
        // sql
        sql.append("insert into `wms_inbound_item` (`id`, `code`, `inbound_code`, `putaway_register_code`, `goods_code`," +
                " `good_code`, `goods_name`, `goods_bar_code`, `spec`, `expiration_quantity`, `goods_unit`, " +
                "`goods_unit_name`, `basic_unit`, `basic_unit_name`, `inbound_quantity`, `location`, `goods_status`, " +
                "`goods_status_name`, `gmt_manufacture`, `gmt_expire`, `gmt_stock`, `status`, `remarks`, `is_deleted`, " +
                "`created_by`, `gmt_created`, `modified_by`, `gmt_modified`, `lot`, `receive_lot`, `supplier`, " +
                "`serial_number`, `extend_one`, `extend_two`, `extend_three`, `extend_four`, `extend_five`, `extend_six`," +
                " `unit_convert_quantity`, `created_name`, `modified_name`, `group_code`) values ");

        String data = inboundItems.stream().map(r -> {
            r.setDeleted(NUM_ZERO);
            return makeInboundSqlStr(r, createdBy, createdName, nowTime);
        }).collect(Collectors.joining(","));
        sql.append(data);

        this.baseMapper.execSql(sql.toString());
    }

    /**
     * 生成批量插入入库单sql数据
     * @param item
     * @param createdBy
     * @param createdName
     * @param nowTime
     * @return
     */
    public String makeInboundSqlStr(InboundItem item, String createdBy, String createdName, LocalDateTime nowTime) {
        item.setGroupCode(UserUtil.getBranchCode());
        StringBuilder data = new StringBuilder();
        data.append("(");
        // id
        data.append("default, ");
        // code
        data.append("'").append(item.getCode()).append("',");
        // inbound_code
        data.append("'").append(item.getInboundCode()).append("',");
        // putaway_register_code
        data.append("'").append(StrUtil.EMPTY).append("',");
        // goods_code
        data.append("'").append(item.getGoodsCode()).append("',");
        // good_code
        data.append("'").append(item.getGoodCode()).append("',");
        // goods_name
        data.append("'").append(item.getGoodsName()).append("',");
        // goods_bar_code
        data.append("'").append(item.getGoodsBarCode()).append("',");
        // spec
        data.append("'").append(ObjectUtil.defaultIfNull(item.getSpec(), StrUtil.EMPTY)).append("',");
        // expiration_quantity
        data.append(ObjectUtil.defaultIfNull(item.getExpirationQuantity(), StrUtil.NULL)).append(",");
        // goods_unit
        data.append("'").append(item.getGoodsUnit()).append("',");
        // goods_unit_name
        data.append("'").append(item.getGoodsUnitName()).append("',");
        // basic_unit
        data.append("'").append(item.getBasicUnit()).append("',");
        // basic_unit_name
        data.append("'").append(item.getBasicUnitName()).append("',");
        // inbound_quantity
        data.append("'").append(item.getInboundQuantity()).append("',");
        // location
        data.append("'").append(item.getLocation()).append("',");
        // goods_status
        data.append("'").append(item.getGoodsStatus()).append("',");
        // goods_status_name
        data.append("'").append(item.getGoodsStatusName()).append("',");
        // gmt_manufacture
        if (ObjectUtil.isNull(item.getGmtManufacture())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getGmtManufacture()).append("',");
        }
        // gmt_expire
        if (ObjectUtil.isNull(item.getGmtExpire())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getGmtExpire()).append("',");
        }
        // gmt_stock
        if (ObjectUtil.isNull(item.getGmtStock())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getGmtStock()).append("',");
        }
        // status
        if (ObjectUtil.isNull(item.getStatus())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getGmtStock()).append("',");
        }
        // remarks
        data.append("'").append(StrUtil.EMPTY).append("',");
        // is_deleted
        data.append("'").append(NUM_ZERO).append("',");
        // created_by
        data.append("'").append(createdBy).append("',");
        // gmt_created
        data.append("'").append(nowTime).append("',");
        // modified_by
        data.append("'").append(createdBy).append("',");
        // gmt_modified
        data.append("'").append(nowTime).append("',");
        // lot
        data.append("'").append(item.getLot()).append("',");
        // receive_lot
        data.append("'").append(ObjectUtil.defaultIfNull(item.getReceiveLot(), StrUtil.EMPTY)).append("',");
        // supplier
        data.append("'").append(ObjectUtil.defaultIfNull(item.getSupplier(), StrUtil.EMPTY)).append("',");
        // serial_number
        data.append("'").append(ObjectUtil.defaultIfNull(item.getSerialNumber(), StrUtil.EMPTY)).append("',");
        // extend_one
        data.append("'").append(ObjectUtil.defaultIfNull(item.getExtendOne(), StrUtil.EMPTY)).append("',");
        // extend_two
        data.append("'").append(ObjectUtil.defaultIfNull(item.getExtendTwo(), StrUtil.EMPTY)).append("',");
        // extend_three
        if (ObjectUtil.isNull(item.getExtendThree())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getExtendThree()).append("',");
        }
        // extend_four
        if (ObjectUtil.isNull(item.getExtendFour())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getExtendFour()).append("',");
        }
        // extend_five
        if (ObjectUtil.isNull(item.getExtendFive())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getExtendFive()).append("',");
        }
        // extend_six
        if (ObjectUtil.isNull(item.getExtendSix())) {
            data.append(StrUtil.NULL).append(",");
        } else {
            data.append("'").append(item.getExtendSix()).append("',");
        }
        // unit_convert_quantity
        data.append("'").append(ObjectUtil.defaultIfNull(item.getUnitConvertQuantity(), NumConst.NUM_ONE)).append("',");
        // created_name
        data.append("'").append(createdName).append("',");
        // modified_name
        data.append("'").append(createdName).append("',");

        data.append("'").append(UserUtil.getBranchCode()).append("' ");

        data.append(")");

        return  data.toString();
    }

    /**
     * 查询列表
     * @return
     */
    @Override
    public List<InboundItemVO> queryInboundGoodsSortQuantity(){
        return this.baseMapper.queryInboundGoodsSortQuantity();
    }
}
